package org.ims.inv.web.action.proficient;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.ims.inv.model.proficient.ModelProficient;
import org.ims.inv.model.system.ModelAppUser;
import org.ims.inv.service.proficient.ServiceProficient;
import org.ims.inv.web.action.BaseAppAction;
import org.ims.inv.web.util.ContextUtil;
import org.ims.inv.web.util.ExcelTemplateSupport;
import org.springframework.beans.BeanUtils;

import cn.trymore.core.util.UtilCollection;
import cn.trymore.core.util.UtilDate;
import cn.trymore.core.util.UtilResources;
import cn.trymore.core.util.UtilString;
import cn.trymore.core.util.excel.AbstractExcelParser;
import cn.trymore.core.util.excel.ExcelRowData;
import cn.trymore.core.util.excel.PoiExcelParser;
import cn.trymore.core.vo.VoTplExcelObj;
import cn.trymore.core.web.paging.PaginationSupport;
import cn.trymore.core.web.paging.PagingBean;

/**
 * Action: 专家管理
 * 
 * @author Jeccy.Zhao
 *
 */
public class ProficientAction
extends BaseAppAction
{
	/**
	 * The LOGGER
	 */
	private static final Logger LOGGER = Logger.getLogger(ProficientAction.class);
	
	/**
	 * The service of proficient
	 */
	private ServiceProficient serviceProficient;
	
	/**
	 * The file upload destination path.
	 */
	private String uploadPath = "";
	
	/**
	 * The file upload temporary path.
	 */
	private String tempPath = "";
	
	/**
	 * 重写
	 */
	private final String MODE_OVERWRITE = "1";
	
	/**
	 * 初始化文件夹
	 */
	private void initFolders ()
	{
		this.uploadPath = UtilResources.getWebRootPath() + "uploads";
		
		File localFile = new File(this.uploadPath);
		if (!localFile.exists())
		{
			localFile.mkdirs();
		}
		
		this.tempPath = this.uploadPath + "/temp";
		File tmpFile = new File(this.tempPath);
		if (!tmpFile.exists())
		{
			tmpFile.mkdirs();
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家管理页面
	 */
	public ActionForward pageProficientIndex (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			ModelProficient formEntity = (ModelProficient) form;
			
			PagingBean pagingBean = this.getPagingBean(request);
			PaginationSupport<ModelProficient> pagingData = 
					this.serviceProficient.getPagination(formEntity, pagingBean);
			
			request.setAttribute("datagrid", pagingData);
			this.outWritePagination(request, pagingBean, pagingData);
			this.outWriteAllParameters(request);
			
			return mapping.findForward("page.proficient.index");
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家导入页面
	 */
	public ActionForward dialogProficientImportPage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		return mapping.findForward("dialog.proficient.import.page");
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家管理弹框页面
	 */
	public ActionForward dialogProficientPage (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String id = request.getParameter("id");
			if (UtilString.isNotEmpty(id))
			{
				if (this.isObjectIdValid(id))
				{
					ModelProficient entity = this.serviceProficient.get(id);
					if (entity != null)
					{
						request.setAttribute("entity", entity);
						
						if (entity.getRecommendTime() != null)
						{
							request.setAttribute("refTime", 
								UtilDate.parseTime(entity.getRecommendTime(), "yyyy-MM-dd"));
						}
						else
						{
							request.setAttribute("refTime", UtilDate.parseTime(new Date(), "yyyy-MM-dd"));
						}
					}
					else
					{
						return ajaxPrint(response, getErrorCallback("数据实体不存在: " + id));
					}
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("非法数据ID: " + id));
				}
			}
			else
			{
				request.setAttribute("refTime", UtilDate.parseTime(new Date(), "yyyy-MM-dd"));
			}
			
			this.outWriteAllParameters(request);
			
			return mapping.findForward("dialog.proficient.form.page");
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家保存
	 */
	public ActionForward actionSaveProficient (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			ModelProficient formEntity = (ModelProficient) form;
			ModelProficient entity = formEntity;
			
			boolean isEditOperation = this.isObjectIdValid(formEntity.getId());
			if (isEditOperation)
			{
				// 编辑
				entity = this.serviceProficient.get(formEntity.getId());
				BeanUtils.copyProperties(formEntity, entity, new String[] { "recommender", "recorder" } );
			}
			else
			{
				entity.setCreationTime(new Date());
				entity.setRecorder(ContextUtil.getCurrentUser());
				entity.setRecommenderName(ContextUtil.getCurrentUser().getUsername());
			}
			
			// 推荐人
			String referralId = request.getParameter("rec.id");
			if (UtilString.isNotEmpty(referralId))
			{
				ModelAppUser referral = this.serviceAppUser.get(referralId);
				if (referral != null)
				{
					entity.setRecommender(referral);
					entity.setRecommenderName(referral.getUsername());
				}
				else
				{
					return ajaxPrint(response, getErrorCallback("推荐人不存在:" + referralId));
				}
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("推荐人不能为空.."));
			}
			
			entity.setRecommendTime(formEntity.getRecommendTime());
			entity.setLastModifiedTime(new Date());
			
			this.serviceProficient.save(entity);
			
			// 保存成功后, Dialog进行关闭
			return ajaxPrint(response, 
					getSuccessCallback("专家信息保存成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家删除
	 */
	public ActionForward actionRemoveProficient (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String id = request.getParameter("id");
			if (this.isObjectIdValid(id))
			{
				ModelProficient entity = this.serviceProficient.get(id);
				if (entity == null)
				{
					return ajaxPrint(response, getErrorCallback("数据实体不存在: " + id));
				}
				
				this.serviceProficient.remove(entity);
				
				return ajaxPrint(response, 
						getSuccessCallback("专家移除成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("非法的数据实体ID: " + id));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家导出
	 */
	public ActionForward actionExportProficient (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			initFolders();
			
			ModelProficient formEntity = (ModelProficient) form;
			
			PagingBean pagingBean = new PagingBean(1, 0);
			PaginationSupport<ModelProficient> pagingData = 
				this.serviceProficient.getPagination(formEntity, pagingBean);
			
			if (pagingData != null && pagingData.getItemCount() > 0)
			{
				VoTplExcelObj obj = ExcelTemplateSupport.getTplObjFromTplFile(
						ExcelTemplateSupport.XLS_TPL_PATH + "/excel.proficient.xml", null);
				
				if (obj != null)
				{
					List<Map<String, Object>> data = new ArrayList<Map<String,Object>>();
					for (ModelProficient entity : pagingData.getItems())
					{
						Map<String, Object> singleRow = new HashMap<String, Object>();
						singleRow.put("proficient", entity);
						data.add(singleRow);
					}
					
					obj = ExcelTemplateSupport.fillTplData(obj, data, null);
					obj.setSheetName("专家信息列表");
					
					String fileName = "exportWorkLog_" + UtilDate.parseTime(new Date(), "yyyyMMddHHmmssSS") + ".xls";
					ExcelTemplateSupport.createExcel(this.tempPath + "/" + fileName, obj);
					
					return ajaxPrint(response, "{status:200, file:'" + "temp/" + fileName + "', name:'" + fileName + "'}");
				}
				else
				{
					return ajaxPrint(response, "{status:500, message:'文件导出失败.'}");
				}
			}
			else
			{
				return ajaxPrint(response, "{status:500, message:'没有可导出的数据.'}");
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, "{status:500, message:'文件导出失败.'}");
		}
	}
	
	/**
	 * <b>[WebAction]</b> 
	 * <br/>
	 * 专家导入
	 */
	public ActionForward actionImportProficient (ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) 
	{
		try
		{
			String mode = request.getParameter("mode");
			String fileUrls = request.getParameter("fileUrls");
			if (UtilString.isNotEmpty(fileUrls))
			{
				String uploadPath = request.getSession().getServletContext().getRealPath("/uploads/");
				AbstractExcelParser excelParser = new PoiExcelParser(uploadPath + "/" + fileUrls);
				List<ExcelRowData> excelRowData = excelParser.getRowData(0);
				
				if (excelRowData == null)
				{
					return ajaxPrint(response, getErrorCallback("模板数据解析错误..."));
				}
				
				if (excelRowData.size() < 3)
				{
					return ajaxPrint(response, getErrorCallback("导入模板格式不正确, 请重新检查..."));
				}
				
				for(int i = 2; i < excelRowData.size();i++)
				{
					ExcelRowData rawData = excelRowData.get(i);
					ModelProficient formEntity = this.convertFromRawData(rawData);
					if (formEntity != null)
					{
						Date nowDate = new Date();
						formEntity.setCreationTime(nowDate);
						formEntity.setLastModifiedTime(nowDate);
						formEntity.setRecorder(ContextUtil.getCurrentUser());
						formEntity.setRecorderName(ContextUtil.getCurrentUser().getUsername());
						
						boolean overWritten = false;
						
						if (MODE_OVERWRITE.equals(mode))
						{
							// 查找是否已存在同名专家
							List<ModelProficient> proficientByName = 
								this.serviceProficient.findProficientByName(formEntity.getFullName());
							
							if (UtilCollection.isNotEmpty(proficientByName))
							{
								for (ModelProficient proficient : proficientByName)
								{
									BeanUtils.copyProperties(formEntity, proficient, new String[] {"id", "recommender", "recorder"});
									proficient.setRecommender(formEntity.getRecommender());
									proficient.setLastModifiedTime(new Date());
									
									this.serviceProficient.save(proficient);
									
									overWritten = true;
								}
							}
						}
						
						if (!overWritten)
						{
							this.serviceProficient.save(formEntity);
						}
					}
				}
				
				return ajaxPrint(response, 
						getSuccessCallback("专家信息导入成功.", CALLBACK_TYPE_CLOSE, CURRENT_NAVTABID, null, false));				
			}
			else
			{
				return ajaxPrint(response, getErrorCallback("需要先上传文件才能导入数据..."));
			}
		}
		catch (Exception e)
		{
			LOGGER.error("Exception raised when loading page", e);
			return ajaxPrint(response, getErrorCallback("数据加载失败,原因:" + e.getMessage()));
		}
	}
	
	/**
	 * 转换excel中的行数据为实体
	 * 
	 * 序号, 姓名, 职称, 院系, 职务, 地址, 手机, 办公室, 邮箱, 推荐项目经理,邀请年份,备注, 研究方向
	 * 0,    1,    2,   3,    4,    5,    6,   7,      8,    9,          10,     11,   12
	 * 
	 * @param rawData
	 * @return
	 * @throws Exception
	 */
	private ModelProficient convertFromRawData (ExcelRowData rawData)
	{
		ModelProficient entity = null;
		
		if (rawData != null)
		{
			String fullName = this.getCellDataByIndexFromRow(rawData, 1);
			if (!UtilString.isNotEmpty(fullName))
			{
				return entity;
			}
			
			entity = new ModelProficient();
			entity.setFullName(fullName);
			entity.setGender(null); //entity.convertFromGenderText(this.getCellDataByIndexFromRow(rawData, 1)));
			
			String birthday = null; //this.getCellDataByIndexFromRow(rawData, 2);
			if (UtilString.isNotEmpty(birthday))
			{
				try
				{
					birthday = UtilDate.parseTime(UtilDate.toDate(this.getCellDataByIndexFromRow(rawData, 2)), "yyyy-MM-dd");
				}
				catch (Exception e)
				{
					LOGGER.error(e);
				}
			}
			entity.setBirthday(birthday);
			
			//序号, 姓名, 职称, 院系, 职务, 地址, 手机, 办公室, 邮箱, 推荐项目经理,邀请年份,备注, 研究方向
			//* 0,    1,    2,   3,    4,    5,    6,   7,      8,    9,          10,     11,   12
			 
			entity.setCompanyName(null); //this.getCellDataByIndexFromRow(rawData, 3));
			entity.setAddress(this.getCellDataByIndexFromRow(rawData, 5));
			entity.setDepartment(this.getCellDataByIndexFromRow(rawData, 3));
			entity.setJobDuty(this.getCellDataByIndexFromRow(rawData, 4));
			entity.setJobTitle(this.getCellDataByIndexFromRow(rawData, 2));
			entity.setOfficePhone(this.getCellDataByIndexFromRow(rawData, 7));
			entity.setMobilePhone(this.getCellDataByIndexFromRow(rawData, 6));
			entity.setEmail(this.getCellDataByIndexFromRow(rawData, 8));
			entity.setBriefing(null); //this.getCellDataByIndexFromRow(rawData, 11));
			entity.setResearchArea(this.getCellDataByIndexFromRow(rawData, 12));
			entity.setReferReason(null); //this.getCellDataByIndexFromRow(rawData, 13));
			entity.setDepartmentComment(this.getCellDataByIndexFromRow(rawData, 11));
			entity.setLeadershipComment(null); //this.getCellDataByIndexFromRow(rawData, 15));
			entity.setRecommenderName(this.getCellDataByIndexFromRow(rawData, 9));
			
			try
			{
				if (UtilString.isNotEmpty(entity.getRecommenderName()))
				{
					ModelAppUser recommender = this.serviceAppUser.findByUserName(entity.getRecommenderName());
					if (recommender != null)
					{
						entity.setRecommender(recommender);
					}
				}
			}
			catch (Exception e)
			{
				LOGGER.error(e);
			}
			
//			String refDate = null; //this.getCellDataByIndexFromRow(rawData, 17); 
//			if (refDate != null)
//			{
//				try
//				{
//					entity.setRecommendTime(UtilDate.toDate(refDate, "yyyy-MM-dd"));
//				}
//				catch (Exception e)
//				{
//					LOGGER.error(e);
//				}
//				
//			}
		}
		
		return entity;
	}
	
	/**
	 * 获取单元格数据
	 * 
	 * @param rawData
	 * @param index
	 * @return
	 */
	private String getCellDataByIndexFromRow (ExcelRowData rawData, int index)
	{
		if (rawData != null)
		{
			if (rawData.getRowData().size() > index)
			{
				if (rawData.getRowData().get(index).trim().equals("null"))
				{
					return null;
				}
				
				return rawData.getRowData().get(index);
			}
		}
		
		return null;
	}
	
	public static Logger getLogger()
	{
		return LOGGER;
	}

	public ServiceProficient getServiceProficient()
	{
		return serviceProficient;
	}

	public void setServiceProficient(ServiceProficient serviceProficient)
	{
		this.serviceProficient = serviceProficient;
	}
	
}
